package com.aidansmeaton.weightmanager;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.aidansmeaton.weightmanager.data.DatabaseHelper;
import com.aidansmeaton.weightmanager.util.ImageHelper;

/** The first activity in the app. */
public class DiaryFoodAddActivity extends Activity {
	
	private static final int GREEN = 0;
	private static final int ORANGE = 1;
	private static final int RED = 2;
	private static final int PURPLE = 3;	

	private static final int CAMERA_PIC_REQUEST = 0;
	
	private DatabaseHelper db;
	private LayoutInflater li;
	private RelativeLayout imageRecognition;
	private LinearLayout listOfPlates;
	private EditText nameOfFood;
	private ImageButton cameraButtonEmpty;
	private ImageButton cameraButtonRemove;
	private TextView noteText;
	private CheckBox check;
	
	private Dialog dialog;
	private Dialog nestedDialog;
	
	private String date;
	private String note;
	private int foodID;
	private int selectedFoodColour;	// currently selected colour
	
	private ViewFlipper flip;
	private Button greenButton;
	private Button orangeButton;
	private Button redButton;
	private Button otherButton;
	
	private String photoPath;
	private OnClickListener plateClick;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.diary_food_add);
        prepareContentView();
        
        // This activity has the theme of a dialog, and will be displayed as such
        setTitle(getString(R.string.diary_record_food_header));
        
        db = DatabaseHelper.getInstance(this);
        li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        date = this.getIntent().getStringExtra("Date");
        foodID = this.getIntent().getIntExtra("Food", -1);
        nameOfFood = (EditText) findViewById(R.id.food_name);
        cameraButtonEmpty = (ImageButton) findViewById(R.id.food_image_empty);
        cameraButtonRemove = (ImageButton) findViewById(R.id.food_image_okay);
        noteText = (TextView) findViewById(R.id.note);
        check = (CheckBox) findViewById(R.id.checkBox);
        imageRecognition = (RelativeLayout) findViewById(R.id.image_recognition);
        listOfPlates = (LinearLayout) findViewById(R.id.ingredient_list);
        selectedFoodColour = 0;
        
    	imageRecognition.setVisibility(View.GONE);
    	cameraButtonRemove.setVisibility(View.GONE);
    	check.setVisibility(View.GONE);
        if (foodID != -1) initialSetUp();
        else ((Button)findViewById(R.id.ingredient_remove)).setEnabled(false);
        
        plateClick = new OnClickListener() {
            public void onClick(View v) {
            	int grade = Integer.parseInt((String)v.getTag());
            	if (grade==0) addIngredientRowToView(grade, "", -1);
            	else addIngredientRowToView(grade, "", 0);
            	if (dialog != null) dialog.dismiss();
            	if (nestedDialog != null) nestedDialog.dismiss();
            }
        };
        
        // stop soft keyboard popping up automatically
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        
	}
    
    /**
	 *  Add plates if in edit mode (rather than recording new)
	 */
	private void initialSetUp() {
		
    	Cursor foodCursor = db.getFoodLog(foodID);
    	Cursor plateCursor = db.getPlateLogs(foodID);
    	
		foodCursor.moveToFirst();
    	if (!foodCursor.isAfterLast()){
    		nameOfFood.setText(foodCursor.getString(DatabaseHelper.FOOD_LOG_NAME));
    		String food_log_note = foodCursor.getString(DatabaseHelper.FOOD_LOG_NOTE);
    		if (food_log_note != null && food_log_note.length() > 0){
    			Log.w("Note",food_log_note);
    			note = food_log_note;
    			noteText.setText(note);
    			imageRecognition.setVisibility(View.VISIBLE);
    		}
    		if (foodCursor.getString(DatabaseHelper.FOOD_LOG_PHOTO) != null){
    			photoPath = foodCursor.getString(DatabaseHelper.FOOD_LOG_PHOTO);
    	    	cameraButtonEmpty.setVisibility(View.GONE);
    	    	cameraButtonRemove.setVisibility(View.VISIBLE);
    	    	check.setVisibility(View.VISIBLE);
    		}
    	}
    	foodCursor.close();
    	
    	plateCursor.moveToFirst();
    	while (!plateCursor.isAfterLast()){
    		int grade = plateCursor.getInt(DatabaseHelper.PLATE_LOG_GRADE);
    		String ingredient = plateCursor.getString(DatabaseHelper.PLATE_LOG_NOTE);   
    		int calories = plateCursor.getInt(DatabaseHelper.PLATE_LOG_CALORIES);
    		
    		addIngredientRowToView(grade,ingredient,calories);
    		plateCursor.moveToNext();
    	}
    	plateCursor.close();
	}
    
	/**
	 *  Push a new ingredient row onto the existing ones
	 */
    private void addIngredientRowToView(int grade, String ingredient, int calories){
	    View view = li.inflate(R.layout.diary_food_plate, null);
		view.setTag(R.id.plate_pic, grade);
		view.setAnimation(AnimationUtils.loadAnimation(this, R.anim.slide_down));
		
		EditText caloriesText = (EditText) view.findViewById(R.id.food_calories);
		if (calories == 0) caloriesText.setVisibility(View.GONE);
		else if (calories == -1) caloriesText.setText("");
		else caloriesText.setText(""+calories);
		
		ImageView icon = (ImageView) view.findViewById(R.id.plate_pic);
		icon.setImageDrawable(this.getResources().getDrawable(ImageHelper.getPlate(grade)));

		EditText foodText = (EditText) view.findViewById(R.id.food_name);
		foodText.setText(ingredient);
		
		listOfPlates.addView(view, 1);
	}
    

    private void prepareContentView() {
    	
    	flip = (ViewFlipper) findViewById(R.id.flip);
        greenButton = (Button) findViewById(R.id.button_green);
        orangeButton = (Button) findViewById(R.id.button_orange);
        redButton = (Button) findViewById(R.id.button_red);
        otherButton = (Button) findViewById(R.id.button_other);
        
        greenButton.setOnLongClickListener(new OnLongClickListener() {
            public boolean onLongClick(View v) {
            	showFoodGroupInfo(GREEN);
                return true;
                }
            });
        
        orangeButton.setOnLongClickListener(new OnLongClickListener() {
            public boolean onLongClick(View v) {
            	showFoodGroupInfo(ORANGE);
                return true;
            }
        });
        
        redButton.setOnLongClickListener(new OnLongClickListener() {
            public boolean onLongClick(View v) {
            	showFoodGroupInfo(RED);
                return true;
            }
        });
        
        otherButton.setOnLongClickListener(new OnLongClickListener() {
            public boolean onLongClick(View v) {
            	showOtherInfo();
                return true;
            }
        });
		
	}
    
    protected void showFoodGroupInfo(final int foodGroup){
    	
    	dialog = new Dialog(this);
    	dialog.setCancelable(true);
    	
    	switch (foodGroup){
    	case (GREEN):
    		dialog.setContentView(R.layout.dialog_ingredient_green);
        	dialog.setTitle(getString(R.string.dialog_ingredient_green_header));
        	break;
    	case (ORANGE):
    		dialog.setContentView(R.layout.dialog_ingredient_orange);
        	dialog.setTitle(getString(R.string.dialog_ingredient_orange_header));
        	break;
    	case (RED):
    		dialog.setContentView(R.layout.dialog_ingredient_red);
        	dialog.setTitle(getString(R.string.dialog_ingredient_red_header));
        	break;
    	}
    	
    	List<ImageView> plates = new ArrayList<ImageView>();
        plates.add((ImageView) dialog.findViewById(R.id.icon_1));
        plates.add((ImageView) dialog.findViewById(R.id.icon_2)); 
        plates.add((ImageView) dialog.findViewById(R.id.icon_3));
        plates.add((ImageView) dialog.findViewById(R.id.icon_4));        
        addPlateClickListeners(plates);
        
        LinearLayout parent = (LinearLayout) dialog.findViewById(R.id.buttons);
        for (int i=0; i < parent.getChildCount(); i++){
        	Button child = (Button) parent.getChildAt(i);
        	child.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                	showPortionSize(v, foodGroup);
                }
            });
        }        
        dialog.show();
    }
    
	
	protected void showOtherInfo() {
    	dialog = new Dialog(this);
        dialog.setContentView(R.layout.dialog_ingredient_other);
        dialog.setTitle(getString(R.string.dialog_ingredient_other_header));
        dialog.setCancelable(true);
        dialog.show();
        
        List<ImageView> plates = new ArrayList<ImageView>();
        plates.add((ImageView) dialog.findViewById(R.id.grey));
        plates.add((ImageView) dialog.findViewById(R.id.purple));        
        addPlateClickListeners(plates);
	}
	
	private void addPlateClickListeners(List<ImageView> list){
		for (ImageView plate : list){
			plate.setOnClickListener(plateClick);
		}
	}
	
	private void showPortionSize(View v, int foodGroup) {	
		
    	nestedDialog = new Dialog(this);
    	nestedDialog.setContentView(R.layout.dialog_ingredient);
    	nestedDialog.setTitle("Portion Size");
    	nestedDialog.setCancelable(true);        
     
        ImageView iv1 = (ImageView) nestedDialog.findViewById(R.id.plate_1);
        ImageView iv2 = (ImageView) nestedDialog.findViewById(R.id.plate_2);
        ImageView iv3 = (ImageView) nestedDialog.findViewById(R.id.plate_3);
        ImageView iv4 = (ImageView) nestedDialog.findViewById(R.id.plate_4);
        
    	iv1.setOnClickListener(plateClick);
    	iv2.setOnClickListener(plateClick);
    	iv3.setOnClickListener(plateClick);
    	iv4.setOnClickListener(plateClick);
        
        switch (foodGroup){
        case (GREEN):
        	iv1.setTag("1");
        	iv2.setTag("2");
        	iv3.setTag("3");
        	iv4.setTag("4");
        	iv1.setImageResource(R.drawable.ic_food_green_1);
        	iv2.setImageResource(R.drawable.ic_food_green_2);
        	iv3.setImageResource(R.drawable.ic_food_green_3);
        	iv4.setImageResource(R.drawable.ic_food_green_4);
        	break;
        case (ORANGE):
        	iv1.setTag("5");
    		iv2.setTag("6");
    		iv3.setTag("7");
    		iv4.setTag("8");
        	iv1.setImageResource(R.drawable.ic_food_orange_1);
	    	iv2.setImageResource(R.drawable.ic_food_orange_2);
	    	iv3.setImageResource(R.drawable.ic_food_orange_3);
	    	iv4.setImageResource(R.drawable.ic_food_orange_4);
	    	break;
        case (RED):
        	iv1.setTag("9");
			iv2.setTag("10");
			iv3.setTag("11");
			iv4.setTag("12");
        	iv1.setImageResource(R.drawable.ic_food_red_1);
	    	iv2.setImageResource(R.drawable.ic_food_red_2);
	    	iv3.setImageResource(R.drawable.ic_food_red_3);
	    	iv4.setImageResource(R.drawable.ic_food_red_4);
	    	break;	
        }        
        
        TextView tiny = (TextView) nestedDialog.findViewById(R.id.text_1);
        TextView small = (TextView) nestedDialog.findViewById(R.id.text_2);
        TextView medium = (TextView) nestedDialog.findViewById(R.id.text_3);
        TextView large = (TextView) nestedDialog.findViewById(R.id.text_4);
        
    	String tag = (String) v.getTag();
        Cursor c = db.getPortionWithTag(tag);
        c.moveToFirst();
        tiny.setText(c.getString(DatabaseHelper.PORTION_TINY));
        small.setText(c.getString(DatabaseHelper.PORTION_SMALL));
        medium.setText(c.getString(DatabaseHelper.PORTION_MEDIUM));
        large.setText(c.getString(DatabaseHelper.PORTION_LARGE));
        
        nestedDialog.show();
	}
    
	public void cameraRemoveClick(View v){
		// TODO Remove image
		Toast.makeText(this, "Photo Removed", Toast.LENGTH_SHORT).show();
		photoPath = null;
    	cameraButtonEmpty.setVisibility(View.VISIBLE);
    	cameraButtonRemove.setVisibility(View.GONE);
    	check.setVisibility(View.GONE);
    } 
    
    public void acceptSuggestionClick(View v){
    	nameOfFood.setText(note);
    }    
    
    public void rejectSuggestionClick(View v){
    	note = null;
    	RelativeLayout imageRecognition = (RelativeLayout) findViewById(R.id.image_recognition);
    	imageRecognition.setVisibility(View.GONE);
    }
    
    public void checkClick(View v){
    	check.setChecked(check.isChecked());
    	if (check.isChecked()) Toast.makeText(this, "Image Recognition Enabled", Toast.LENGTH_SHORT).show();
    	else Toast.makeText(this, "Image Recognition Disabled", Toast.LENGTH_SHORT).show();
    }

	public void okayClick(View v){
    	
    	String name = (String) nameOfFood.getText().toString();
    	
    	ContentValues cv = new ContentValues();
    	
    	if (foodID != -1){
    		cv.put("_id", foodID);
    		db.deletePlateLogsFromFoodID((int)foodID);
    	}
    	else cv.putNull("_id");
    	cv.put("date", date);
    	cv.put("meal", 1);
    	if (name != null) cv.put("name", name); else cv.putNull("name");
    	cv.putNull("measurement");
    	cv.put("quantity", 1);
    	if (note != null) cv.put("note", note); else cv.putNull("note");
    	if (photoPath != null){
    		cv.put("photo", photoPath); 
    		if (check.isChecked() && (note==null || note.length() < 1)){
    			Intent imageRecognition = new Intent(this, ImageRecognitionService.class);
        		imageRecognition.putExtra("photoPath", photoPath);
        	    startService(imageRecognition);
    		}
    	} else cv.putNull("photo");
    	
    	long food_id;
    	if (foodID != -1) food_id = db.editFoodLog(cv);
    	else food_id = db.addFoodLog(cv);
    	
    	LinearLayout layout = (LinearLayout) findViewById(R.id.ingredient_list);
    	int ingredientCount = layout.getChildCount();
    	
    	// if there are no ingredients, add stub
    	if (ingredientCount == 1){
    		ContentValues cv2 = new ContentValues();
        	cv2.putNull("_id");
        	cv2.put("food_log_id", food_id);
        	cv2.put("grade", 13);
        	cv2.put("note","To be filled in");
        	cv2.putNull("calories");
        	db.addPlateLog(cv2);
    	}
    	
    	// add the ingredients
    	else {
	    	for (int i=1; i<ingredientCount; i++){	// start at 1 because first child is selection header
	    		LinearLayout ingredient = (LinearLayout) layout.getChildAt(i);
	    		int grade = (Integer) ingredient.getTag(R.id.plate_pic);
	    		EditText ingredientText = (EditText) ((LinearLayout)ingredient.getChildAt(1)).getChildAt(1);
	    		String note = ingredientText.getText().toString();
	    		String calories = "0";
	    		if (!(grade >= 1 && grade <= 13)){
	    			EditText caloriesText = (EditText) ((LinearLayout)ingredient.getChildAt(1)).getChildAt(0);
	        		calories = caloriesText.getText().toString();
	    		}
	    		boolean correctlyFormatted = true;
	    		ContentValues cv2 = new ContentValues();
	        	cv2.putNull("_id");
	        	cv2.put("food_log_id", food_id);
	        	cv2.put("grade", grade);
	        	if (note != null) cv2.put("note", note); else cv2.putNull("note");
	        	if (!(grade >= 1 && grade <= 13)){
	        		try {
	        			cv2.put("calories", Integer.parseInt(calories));
	        		} catch (Exception e) {
	        			cv2.putNull("calories");
	        			correctlyFormatted = false;
	        		}
	        	}
	        	else cv2.putNull("calories");
	        	if (correctlyFormatted) db.addPlateLog(cv2);
	    	}
    	}
    	finish();
	}
    
    public void cancelClick(View v){
    	finish();    	
    }
    
    public void removeClick(View v){
    	
    	final Dialog dialog = new Dialog(this);
    	dialog.setContentView(R.layout.dialog_remove);
    	dialog.setTitle("Remove Food?");
    	dialog.setCancelable(true);
    	
    	// force width to fill parent
    	LayoutParams params = dialog.getWindow().getAttributes(); 
        params.width = LayoutParams.FILL_PARENT; 
        dialog.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
        
        Button cancel = (Button) dialog.findViewById(R.id.cancel);
        cancel.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
            	dialog.dismiss();
            }
        });    	
    
        Button remove = (Button) dialog.findViewById(R.id.remove);
        remove.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
            	dialog.dismiss();
            	db.deleteFoodLog(foodID);
            	if (photoPath != null){
            		// TODO delete photo
            	}
            	finish();
            }
        });
        
        dialog.show();
    }
    
    public void removeIngredientClick(View v){
    	// find view for whole row, and remove it
    	LinearLayout row = (LinearLayout) v.getParent().getParent();
    	ViewGroup parent = (ViewGroup) row.getParent();
    	parent.removeView(row);
    }
    
    public void colourClick(View v){
    	Button button = (Button) v;
    	String tag = (String) button.getTag();
    	
    	Button back = (Button) findViewById(R.id.portion_back);
    	ImageView portion1 = (ImageView) findViewById(R.id.portion_1);
    	ImageView portion2 = (ImageView) findViewById(R.id.portion_2);
    	ImageView portion3 = (ImageView) findViewById(R.id.portion_3);
    	ImageView portion4 = (ImageView) findViewById(R.id.portion_4);
    	
    	portion1.setVisibility(View.VISIBLE);
    	portion2.setVisibility(View.VISIBLE);
    	portion3.setVisibility(View.VISIBLE);
    	portion4.setVisibility(View.VISIBLE);
    	
    	if (tag.equals(getString(R.string.diary_food_colour_green))){
    		selectedFoodColour = GREEN;
    		back.setBackgroundResource(R.drawable.btn_green);
    		//back.setText(R.string.diary_food_colour_green);
        	portion1.setImageResource(R.drawable.ic_food_green_1);
        	portion2.setImageResource(R.drawable.ic_food_green_2);
        	portion3.setImageResource(R.drawable.ic_food_green_3);
        	portion4.setImageResource(R.drawable.ic_food_green_4);
    	}
    	else if (tag.equals(getString(R.string.diary_food_colour_orange))){
    		selectedFoodColour = ORANGE;
    		back.setBackgroundResource(R.drawable.btn_yellow);
    		//back.setText(R.string.diary_food_colour_orange);
        	portion1.setImageResource(R.drawable.ic_food_orange_1);
        	portion2.setImageResource(R.drawable.ic_food_orange_2);
        	portion3.setImageResource(R.drawable.ic_food_orange_3);
        	portion4.setImageResource(R.drawable.ic_food_orange_4);
    	}
    	else if (tag.equals(getString(R.string.diary_food_colour_red))){
    		selectedFoodColour = RED;
    		back.setBackgroundResource(R.drawable.btn_red);
    		//back.setText(R.string.diary_food_colour_red);
        	portion1.setImageResource(R.drawable.ic_food_red_1);
        	portion2.setImageResource(R.drawable.ic_food_red_2);
        	portion3.setImageResource(R.drawable.ic_food_red_3);
        	portion4.setImageResource(R.drawable.ic_food_red_4);
    	}
    	else {
    		selectedFoodColour = PURPLE;
    		back.setBackgroundResource(R.drawable.btn_purple);
    		//back.setText(R.string.diary_food_colour_other);
    		portion1.setImageResource(R.drawable.ic_food_purple);
    		portion2.setImageResource(R.drawable.ic_food_grey);
        	portion3.setVisibility(View.GONE);
        	portion4.setVisibility(View.GONE);
    	}
    	ViewFlipper flip = (ViewFlipper)findViewById(R.id.flip);
    	flip.setInAnimation(this,android.R.anim.slide_in_left);
    	flip.setOutAnimation(this, android.R.anim.slide_out_right);
    	flip.showNext();
    }
    
    public void skipClick(View v){
    	flip.showNext();
    }
    
    public void portionSizeClick(View v){
    	int plateGrade = (Integer.parseInt((String) v.getTag())) + (4 * selectedFoodColour);
    	if (plateGrade >= 1 && plateGrade <= 13) addIngredientRowToView(plateGrade, "", 0);
    	else addIngredientRowToView(plateGrade, "", -1);
    }
    
    /*
     *  Callback for when a plate in an ingredient row is clicked
     */
    public void plateClick(View v){
    	int grade = (int)(Integer)((View)v.getParent()).getTag(R.id.plate_pic);
    	switch (grade){
    	case (1):	showFoodGroupInfo(GREEN);	break;
    	case (2):	showFoodGroupInfo(GREEN);	break;
    	case (3):	showFoodGroupInfo(GREEN);	break;
    	case (4):	showFoodGroupInfo(GREEN);	break;
    	case (5):	showFoodGroupInfo(ORANGE);	break;
    	case (6):	showFoodGroupInfo(ORANGE);	break;
    	case (7):	showFoodGroupInfo(ORANGE);	break;
    	case (8):	showFoodGroupInfo(ORANGE);	break;
    	case (9):	showFoodGroupInfo(RED);		break;
    	case (10):	showFoodGroupInfo(RED);		break;
    	case (11):	showFoodGroupInfo(RED);		break;
    	case (12):	showFoodGroupInfo(RED);		break;
    	default:	showFoodGroupInfo(PURPLE);	break;
    	}
    }
    
    
    public void cameraClick(View v){
    	try {
    	Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
    	} catch (Exception e) {
    		Toast.makeText(this, getString(R.string.error_camera), Toast.LENGTH_SHORT).show();
    	}
    }
    
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if (requestCode == CAMERA_PIC_REQUEST) {  
        	try {
            	Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            	String filename = "food_photo_"+System.currentTimeMillis();
        		FileOutputStream fos = openFileOutput(filename, Context.MODE_WORLD_READABLE);
        		thumbnail.compress(Bitmap.CompressFormat.JPEG, 70, fos);
        		fos.close();
        		
        		//TODO Check for old photo and delete        		
        		
        		photoPath = filename;

    	    	cameraButtonEmpty.setVisibility(View.GONE);
    	    	cameraButtonRemove.setVisibility(View.VISIBLE);
    	    	check.setVisibility(View.VISIBLE);
        		
        		Toast.makeText(this, "Picture saved", Toast.LENGTH_SHORT).show();
        		
        	} catch (Exception e){
        		e.printStackTrace();
        	}
        }
    }
}